function htmlEncode(str, isReplaceSpace){ 
	if(str && typeof str == 'string') {
  		str = str.replace(/&/g,"&#38;").replace(/</g,"&lt;").replace(/>/g, '&gt;').replace(/"/g, '\"');
  		isReplaceSpace && (str = str.replace(/\s{2,}/g, function(m){
  			return m.substring(0,m.length-1).replace(/\s/g,"&nbsp;")+" ";
  		}));
	}
  	return str;
};
//属性编码
function varEncode(str, isReplaceSpace){
	if(str && typeof str == 'string') {
  		str = str.replace(/&/g,"&#38;").replace(/</g,"&lt;").replace(/>/g, '&gt;').replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/\]/g, "&#93;").replace(/\[/g, "&#91;");
		isReplaceSpace && (str = str.replace(/\s{2,}/g, function(m){
			return m.substring(0,m.length-1).replace(/\s/g,"&nbsp;")+" ";
		}));
	}
  	return str;
}
function tmplValue(obj, encode, isReplaceSpace){
	if(obj !== void 0)
	{
		if($.isPlainObject(obj) && !$.isEmptyObject(obj))
			return Ccay.DataHelper.toJsonStr(obj);

		return encode > 0 ? (encode ==1 ? htmlEncode(obj, isReplaceSpace)  : varEncode(obj, isReplaceSpace)) : obj;
	}
	return '';
};

Ccay.UI.template = function(tmpl,datas,startIndex,key,args, isReplaceSpace){
	if(tmpl)
	{
		//获取模板
        if(key && this[key])
        	tmpl = this[key];
        else
        {
        	if(typeof(tmpl) == "object")
        		tmpl = tmpl.html();
        	
        	if(key)
        		this[key] = tmpl;
        }
        if(tmpl)
        {
	        //模板定义转化
        	tmpl = tmpl.replace(/\r|\n/g,"").replace(/("|\\)/g,"\\$1").replace(/\<\%([\s\S]*?)\%\>/g, '");\n $1 _s.push("')
	            .replace(/\${([\s\S]*?)}/g, function (s, m) {
	            	var sign = m.substr(0,1),type = 1;
	            	if(sign == '#')
	            		type = 0;
	            	else if(sign == '&')
	            		type = 2;

	            	return '"); try{_s.push(tmplValue(' + (type==1 ? m : m.substring(1)) + "," + type + "," + isReplaceSpace +'))}catch(e){Ccay.Core.log(e && e.message);};_s.push("';
            });
        	
//        	.replace(/\r|\n/g,"").replace(/("|\\)/g,"\\$1")
//        				.replace(/<\%/g,'");\n').replace(/\%>/g,'_s.push("')
//        				.replace(/\${#([\s\S]*?)\}/g, '",tmplValue($1),"')
//        				.replace(/\${([\s\S]*?)\}/g, '",tmplValue($1,1),"');

	        //绑定数据处理
	        var _a = [],_v = [],i;
       		for (i in datas){
              _a.push(i);
              _v.push(datas[i]);
       		} 
       		if(args){
				for (i in args){
	              _a.push(i);
	              _v.push(args[i]);
	       		} 
       		}	
	       	_a.push('index');
	       	_v.push(startIndex || 1);

	       return (new Function(_a,'var _s=[];_s.push("'+ tmpl+'"); return _s;')).apply(null,_v).join("");
       }
       else
       		return "";
	}
};
Ccay.UI.multiTmplList = function(tmpl,datas,mapping,startIndex,key){
	if(tmpl && datas)
	{
		if(typeof(tmpl) == "object")
    		tmpl = tmpl.html();
		
		if(!mapping)
			mapping = 'datas';
		
		var def = [], tms = [],res = ["\n return ["],len = tmpl.length - 1;
		$.each(tmpl,function(i,t){
			if(t){
				var n = "_s" + i;
				tms.push(n,'.push("',t.replace(/\r|\n/g,"").replace(/("|\\)/g,"\\$1")
				.replace(/<\%/g,'");\n').replace(/\%>/g,n +'.push("')
				.replace(/\${#([\s\S]*?)\}/g, '",tmplValue($1),"')
				.replace(/\${([\s\S]*?)\}/g, '",tmplValue($1,1),"'),'");');
				def.push(n+'=[]')
				res.push(i==0 ? n : ',' + n,".join('')");
			}
			
		});
		tmpl = "var " + def.join(",") + ";for (var i=0,data=" + mapping + "[0]; data; i ++,index++,data =" + mapping + "[i]) { with(data){" + 
			tms.join("") + "}};" +res.join("") + ']';

		//绑定数据处理
        var _a = ["datas","index"],_v = [datas,startIndex || 1];

       return (new Function(_a,tmpl)).apply(null,_v);
	}
	else
		return "";
};

Ccay.UI.tmplList = function(tmpl,datas,mapping,startIndex,key,args, isReplaceSpace){
	if(tmpl && datas)
	{
		if(typeof(tmpl) == "object")
    		tmpl = tmpl.html();
		
		if(!mapping)
			mapping = 'datas';
		tmpl = "<%for (var i=0,data; data =" + mapping + "[i]; i ++,index++) { with(data){ %>" + tmpl + "<% }}; %>";
		var datasource = {};
		datasource[mapping] = datas;
		return Ccay.UI.template(tmpl,datasource,startIndex,key,args, isReplaceSpace);
	}
	else
		return "";
};

(function ($) {
	$.fn.ccayTemplate=function(op,datas){
		op = $.extend({
			tmpl:null,
			key:null,
			insertPosition:null,
			ajax:null
		},op);
		
		if(op.tmpl)
		{
			var target = this;
			if(datas)
				template.build(target,op,datas);
			else if(op.ajax)
			{
				ajax = Ccay.UI.ajax.setFnSuccess(op.ajax,function(data){
					template.build(target,op,$.isPlainObject(data) ? data.result : data);
				});
				
				Ccay.UI.ajax(op.ajax,target);
			}
		}
	}
	
	var template = {
		build:function(target,op,datas,mapping){
			var html = $.isArray(datas) ? Ccay.UI.tmplList(op.tmpl,datas,mapping,op.startIndex,op.key) : 
				Ccay.UI.template(op.tmpl,datas,op.startIndex,op.key);
			if(op.insertPosition)
				$.fn[op.insertPosition].apply(target,[html]);
			else
				target.html(html);
			return target;
		},
		buildHtml:function(target,datas){
			return target.each(function(){
			var body = $(this);
			//列表模板
			body.find('.ccay-tmpl-list').each(function(){
				var container = $(this),
					mapping = container.attr('mapping') || 'datas';
					
				if(mapping && datas[mapping])
					template.setHtmlTmpl($(this),datas[mapping],mapping);
			});
			//普通模�?
			body.find('.ccay-tmpl').each(function(){
				template.setHtmlTmpl($(this),datas);
			});
		});
		},
		setHtmlTmpl:function(target,datas,mapping){
			var child = target.children(':first'),tmpl;
			if(child.length && child[0].tagName.toLowerCase() == 'script')
				tmpl = child.html();
			else
				tmpl = target.html();

			if(tmpl)
				template.build(target,{tmpl:tmpl.trim()},datas,mapping);
		}
	};
	
	$.fn.ccayHtmlTemplate=function(ajax,datas){
		if(this.length)
		{
			var target = this;
			if(datas)
				template.buildHtml(target,datas);
			else if(ajax)
			{
				Ccay.UI.ajax.setFnSuccess(ajax,function(data){
					template.buildHtml(target,data);
				},1);
				
				Ccay.UI.ajax(ajax,target);
			}
		}
	}
})(jQuery);


